package online.inote.naruto.api.access.admin.modules.system.controller;

import online.inote.naruto.api.access.admin.modules.base.controller.BaseController;
import online.inote.naruto.api.access.admin.modules.system.entity.ApiEntity;
import online.inote.naruto.api.access.admin.modules.system.entity.SystemEntity;
import online.inote.naruto.api.access.admin.modules.system.service.ApiService;
import online.inote.naruto.api.access.props.ApiAccessProperties;
import online.inote.naruto.cache.CacheSupport;
import online.inote.naruto.common.utils.response.Code;
import online.inote.naruto.common.utils.response.ExtendResponse;
import online.inote.naruto.common.utils.response.Response;
import online.inote.naruto.utils.Page;
import online.inote.naruto.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @description API Controller
 * @author XQF.Sui
 * @date 2021/08/05 18:27
 */
@RestController
@RequestMapping(value = "api")
public class ApiController extends BaseController {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  private final ApiService apiService;
  private final ApiAccessProperties apiProps;

  public ApiController(ApiService apiService, ApiAccessProperties apiProps) {
    this.apiService = apiService;
    this.apiProps = apiProps;
  }

  @PostMapping(value = "save")
  public Response<Object> save(@Valid @RequestBody ApiEntity apiEntity, BindingResult result) {
    if (result.hasErrors()) {
      return ExtendResponse.fail(
          StringUtils.join(
              result.getAllErrors().stream()
                  .map(ObjectError::getDefaultMessage)
                  .collect(Collectors.toList())));
    }

    try {
      apiService.save(apiEntity);
    } catch (Exception e) {
      if (e instanceof DuplicateKeyException) {
        logger.error("API已存在，保存失败", e);
        return ExtendResponse.fail("API已存在，保存失败");
      }

      logger.error("保存失败", e);
      return ExtendResponse.fail("保存失败");
    }

    return ExtendResponse.success();
  }

  @GetMapping(value = "details/{id}")
  public Response<Object> details(@PathVariable String id) {
    Optional<ApiEntity> optional = apiService.details(id);

    if (!optional.isPresent()) {
      return ExtendResponse.fail("未查询到改接口信息");
    }

    ApiEntity apiEntity = optional.get();

    apiEntity.setAuthSystemNumber(
        CacheSupport.count(apiProps.getCache().initInterfaceAuthSystemCacheKey(id)));

    return ExtendResponse.success(apiEntity);
  }

  @PostMapping(value = "getPage")
  public Response<Page<ApiEntity>> getPage(@RequestBody Page<ApiEntity> page) {
    apiService.getPage(page);
    return ExtendResponse.success(page);
  }

  @PostMapping(value = "enable")
  public Response<SystemEntity> enable(@RequestBody ApiEntity api) {

    if (StringUtils.isBlank(api.getId()) || Objects.isNull(api.getEnable())) {
      return ExtendResponse.create(Code.PARAM_REQUIRED);
    }

    Optional<ApiEntity> optional = apiService.details(api.getId());

    if (!optional.isPresent()) {
      return ExtendResponse.fail("未查询到对于的API信息");
    }

    ApiEntity existsApiInfo = optional.get();

    existsApiInfo.setEnable(api.getEnable());
    apiService.save(existsApiInfo);

    return ExtendResponse.success();
  }
}
